package com.acooly.module.openapi.client.provider.baofup.signature;

import com.acooly.module.openapi.client.provider.baofup.BaoFuPConstants;
import com.acooly.module.safety.exception.SignatureVerifyException;
import com.acooly.module.safety.signature.Signer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author zhike 2017/11/28 11:41
 */
@Component("safetyBaoFuPMd5Signer")
@Slf4j
public class BaoFuPMd5Signer implements Signer<LinkedHashMap<String, String>, String> {

    @Override
    public String sign(LinkedHashMap<String, String> plain, String key) {
        String returnSignStr = null;
        try {
            String waitToSignStr = getWaitToSigin(plain);
            // MD5摘要签名计算
            MessageDigest messageDigest = DigestUtils.getMd5Digest();
            messageDigest = DigestUtils.updateDigest(messageDigest, waitToSignStr + "&key=" + key);
            byte[] digest = messageDigest.digest();
            StringBuffer hexString = new StringBuffer();
            String strTemp;
            for (int i = 0; i < digest.length; i++) {
                strTemp = Integer.toHexString((digest[i] & 0x000000FF) | 0xFFFFFF00).substring(6);
                hexString.append(strTemp);
            }
            returnSignStr = hexString.toString();
        } catch (Exception e) {
            log.info("签名异常：{}", e.getMessage());
        }
        return returnSignStr;
    }

    @Override
    public void verify(LinkedHashMap<String, String> plain, String key, String verifySign) {
        String waitToSignStr = getWaitToSigin(plain);
        // MD5摘要签名计算
        String signature = DigestUtils.md5Hex(waitToSignStr + "&key=" + key);
        if (!verifySign.equalsIgnoreCase(signature)) {
            throw new SignatureVerifyException("验签未通过");
        }
    }

    protected String getWaitToSigin(LinkedHashMap<String, String> plain) {
        String waitToSignStr = null;
        if (plain.containsKey("sign")) {
            plain.remove("sign");
        }

        StringBuilder stringToSign = new StringBuilder();
        if (plain.size() > 0) {
            Iterator var5 = plain.entrySet().iterator();

            while (var5.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry) var5.next();
                if (entry.getValue() != null) {
                    stringToSign.append((String) entry.getKey()).append("=").append((String) entry.getValue()).append("&");
                }
            }

            stringToSign.deleteCharAt(stringToSign.length() - 1);
            waitToSignStr = stringToSign.toString();
        }

        return waitToSignStr;
    }

    @Override
    public String getSinType() {
        return BaoFuPConstants.SIGNER_TYPE;
    }
}




